/*
 *      stone.cpp
 *      
 *      Copyright 2008 Antti Leivo <skylark@skylark-desktop>
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */


#include <iostream>
#include "stone.h"

#define DEBUG_LEVEL 1

Stone::Stone(StoneForm _form, float _x, float _y, float _vx, float _vy, float _angle, float _angvel)
	: form(_form), space(0), body(0), shape(0)
{

	if (_form.type == stBall)
	{
		/* create stone ball */
     	float r = _form.width/2;
     	float mass = 4.0/3.0*3.14159265 * STONE_DENSITY_KGM3 * r*r*r;
		body = cpBodyNew(mass, /*J of uniform solid sphere*/0.4*mass*r*r);
		shape = cpCircleShapeNew(body, /*radius*/r, cpv(0,0));
	}
	else {
		/* create stone box */
		float mass = STONE_DENSITY_KGM3 * _form.height*_form.width*(_form.height+_form.width/2);
		body = cpBodyNew(mass, /*J of box*/(1.0/12.0)*mass*(_form.width*_form.width + _form.height*_form.height));
		float w2 = _form.width/2;
		float h2 = _form.height/2;
		cpVect verts[4];
		verts[3] = cpv(-w2, -h2);
		verts[2] = cpv( w2, -h2);
		verts[1] = cpv( w2,  h2);
		verts[0] = cpv(-w2,  h2);
		shape = cpPolyShapeNew(body, 4, verts, cpv(0,0));
	}

	body->p = cpv(_x, _y);
	body->v = cpv(_vx, _vy);
	cpBodySetAngle(body, _angle);
	body->w = _angvel; /* rad/s */

	shape->e = 0.75;            /* elasticity 0..1 */
	shape->u = 0.2;            /* friction 0..1 */
	shape->collision_type = 1; /* ? */

    //optional collision callback-fnc: cpSpaceAddCollisionPairFunc(space, 1, 0, &collFunc, &some_value);

}


Stone::~Stone()
{
	if (shape != 0 && body != 0)
	{
		cpShapeFree(shape);
		cpBodyFree(body);
	}
}

void Stone::attachCpSpace(cpSpace *_space)
{
	if (_space == 0 || space != 0)
	{
		#if (DEBUG_LEVEL >= 1)
			std::cout << "STONE::attachCpStone: Error: NULL spaces "
			<< "(ext=" << _space << ", own=" << space << ")" << std::endl;
		#endif
		return;
	}
		
	space = _space;
	cpSpaceAddBody(space, body);
	cpSpaceAddShape(space, shape);
}

StoneForm::StoneForm(float _radius)
	: type(stBall), width(2*_radius), height(2*_radius)
{
}

StoneForm::StoneForm(float _width, float _height)
	: type(stBox), width(_width), height(_height)
{
}

